package com.example.aspect.demo;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
@Aspect //作用是把当前类标识为一个切面供容器读取
    @Component
    public class HttpAspect {

        //使用org.slf4j.Logger,这是Spring实现日志的方法
        private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

        /**
         * execution(方法修饰符(可选)  返回类型  方法名  参数  异常模式(可选))
         * 修饰符 通配符(*表示所有，可定义void\String 返回值为具体类型的方法) 包名 类名 方法名 参数
         * 定义AOP扫描的路径，第一个路径只扫描controller中的一个方法，两个点表示任何参数
         */
//        @Pointcut("execution( public * com.example.aspect.demo.controller.AspectTestController.*(..))&&args( account,..))")
//        public void  log(int account){
//
//        }
//
//        /**
//         * 记录Http请求开始的日志
//         */
//        @Before("log( int ) )") //标识一个前置增强方法，相当于BeforeAdvice的功能
//        public void doBefore(JoinPoint joinPoint) throws Throwable{
//            System.out.println("HttpAspect ###Before");
//            // 接收到请求，记录请求内容
//            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//            HttpServletRequest request = attributes.getRequest();
//            // 记录下请求内容
//            System.out.println("URL : " + request.getRequestURL().toString());
//            System.out.println("HTTP_METHOD : " + request.getMethod());
//            System.out.println("IP : " + request.getRemoteAddr());
//            System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
//            System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));
//
//        }
//
//        //环绕通知,环绕增强，相当于MethodInterceptor
//        @Around("log( int ) )")
//        public Object arround(ProceedingJoinPoint pjp) {
//            System.out.println("方法环绕start.....");
//            try {
//                Object o =  pjp.proceed();//执行方法
//                System.out.println("方法环绕proceed，结果是 :" + o);
//
//                return o;
//            } catch (Throwable e) {
//                e.printStackTrace();
//                return null;
//            }
//        }
//
//        /**
//         * 后置异常通知
//         * */
//        @AfterThrowing("log(int ) )&& args(param)")
//        public void throwss(JoinPoint jp){
//            System.out.println("方法异常时执行.....");
//        }

        /**
         * 记录HTTP请求结束时的日志
         * 后置最终通知,final增强，不管是抛出异常或者正常退出都会执行
         */
        @After("execution( public * com.example.aspect.demo.controller.AspectTestController.*(..))&&args(..,account1,name))")
        public void doAfter(int account1,String name){
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();

         //   System.out.println("HttpAspect ###After");
        //    System.out.println("execution :"+request.getRequestURL());
            System.out.println(account1);
            System.out.println(name);

        }

        /**
         * 获取返回内容
         * @param object
         */
//        @AfterReturning(returning = "object",pointcut = "log(int)")
//        public void doAfterReturn(Object object){
//            System.out.println("HttpAspect ###AfterReturn");
//            System.out.println("response :"+object.toString());
//        }


        @Around( "execution(public * com.example.aspect.demo.controller.AspectTestController.*(..))&& " +
                "@annotation(org.springframework.web.bind.annotation.GetMapping)")
        public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("-------------------hahahahah------------------------------------------------------");
            return  null;
        }
}
